<template>
  <div class="parent-component">
    <div class="p-5">
      <h2 class="text-center mb-8 text-2xl font-bold text-white drop-shadow-lg">
        Vue3 父子组件生命周期演示
      </h2>

      <!-- 生命周期状态显示 -->
      <div class="bg-white bg-opacity-10 p-5 rounded-lg mb-5 backdrop-blur-sm">
        <h3 class="mb-4 text-yellow-300 font-semibold">父组件生命周期状态：</h3>
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2">
          <div
            v-for="status in lifecycleStatus"
            :key="status.name"
            :class="['status-item', status.executed ? 'executed' : 'pending']"
          >
            {{ status.name }}: {{ status.executed ? '✅ 已执行' : '⏳ 未执行' }}
            <span v-if="status.time" class="text-xs opacity-80 ml-2">{{ status.time }}</span>
          </div>
        </div>
      </div>

      <!-- 控制按钮 -->
      <div class="flex gap-4 mb-5 flex-wrap">
        <button @click="toggleChild" class="control-btn">
          {{ showChild ? '隐藏子组件' : '显示子组件' }}
        </button>
        <button @click="updateParentData" class="control-btn">更新父组件数据</button>
        <button @click="clearLogs" class="control-btn">清除控制台日志</button>
      </div>

      <!-- 父组件数据显示 -->
      <div class="bg-white bg-opacity-10 p-4 rounded-lg mb-5">
        <h3 class="text-yellow-300 mb-2 font-semibold">父组件数据：</h3>
        <p class="my-1 font-mono text-sm">更新次数: {{ parentCounter }}</p>
        <p class="my-1 font-mono text-sm">子组件消息: {{ parentMessage }}</p>
      </div>

      <!-- 子组件 -->
      <div
        v-if="showChild"
        class="mt-5 p-5 bg-white bg-opacity-5 rounded-lg border-2 border-dashed border-white border-opacity-30"
      >
        <ChildComponent
          :counter="parentCounter"
          :message="parentMessage"
          @child-event="handleChildEvent"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  reactive,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onActivated,
  onDeactivated,
  watch,
  nextTick,
} from 'vue'
import ChildComponent from './ChildComponent.vue'

// 响应式数据
const parentCounter = ref(0)
const parentMessage = ref('等待子组件消息...')
const showChild = ref(true)

// 生命周期状态追踪
const lifecycleStatus = reactive([
  { name: 'setup', executed: true, time: new Date().toLocaleTimeString() },
  { name: 'onBeforeMount', executed: false, time: '' },
  { name: 'onMounted', executed: false, time: '' },
  { name: 'onBeforeUnmount', executed: false, time: '' },
  { name: 'onUnmounted', executed: false, time: '' },
])

// 辅助函数：更新生命周期状态
const updateLifecycleStatus = (name: string) => {
  const status = lifecycleStatus.find((s) => s.name === name)
  if (status) {
    status.executed = true
    status.time = new Date().toLocaleTimeString()
  }
}

// 辅助函数：控制台日志
const logLifecycle = (phase: string, component: string = 'Parent') => {
  console.log(`🔄 [${component}] ${phase} - ${new Date().toLocaleTimeString()}`)
}

// setup阶段
console.log('🚀 [Parent] setup开始 - 组件实例创建，响应式数据初始化')
logLifecycle('setup执行')

// 生命周期钩子
onBeforeMount(() => {
  logLifecycle('onBeforeMount - 组件挂载前，DOM还未创建')
  updateLifecycleStatus('onBeforeMount')
})

onMounted(() => {
  logLifecycle('onMounted - 组件挂载完成，DOM已创建并插入页面')
  updateLifecycleStatus('onMounted')
})

// 注意：onBeforeUpdate 和 onUpdated 会在任何响应式数据变化时触发
// 为避免无限循环，我们只在控制台记录，不更新页面状态
onBeforeUpdate(() => {
  logLifecycle('onBeforeUpdate - 响应式数据变化，DOM更新前')
  // 移除状态更新，避免无限循环：updateLifecycleStatus('onBeforeUpdate')
})

onUpdated(() => {
  logLifecycle('onUpdated - DOM更新完成')
  // 移除状态更新，避免无限循环：updateLifecycleStatus('onUpdated')
})

onBeforeUnmount(() => {
  logLifecycle('onBeforeUnmount - 组件卸载前')
  updateLifecycleStatus('onBeforeUnmount')
})

onUnmounted(() => {
  logLifecycle('onUnmounted - 组件卸载完成，清理工作完成')
  updateLifecycleStatus('onUnmounted')
})

// Keep-alive相关生命周期（如果需要的话）
onActivated(() => {
  logLifecycle('onActivated - keep-alive组件激活')
})

onDeactivated(() => {
  logLifecycle('onDeactivated - keep-alive组件停用')
})

// 监听器
watch(
  () => parentCounter.value,
  (newVal, oldVal) => {
    console.log(`👀 [Parent] watch - parentCounter从 ${oldVal} 变为 ${newVal}`)
  },
)

// 方法
const toggleChild = () => {
  showChild.value = !showChild.value
  logLifecycle(`${showChild.value ? '显示' : '隐藏'}子组件`)
}

const updateParentData = async () => {
  parentCounter.value++
  // 不再更新消息，消息用来显示从子组件接收到的数据
  logLifecycle(`触发第${parentCounter.value}次数据更新`)

  // 使用nextTick确保DOM更新后执行
  await nextTick()
  console.log('✅ [Parent] nextTick - DOM更新完成后执行')
}

const handleChildEvent = (data: any) => {
  console.log('📨 [Parent] 接收到子组件事件:', data)
  // 更新消息字段来显示从子组件接收到的消息
  parentMessage.value = `来自子组件: ${data.payload.message} (${data.payload.timestamp})`
}

const clearLogs = () => {
  console.clear()
  console.log('🧹 控制台日志已清除')
  console.log('💡 请继续操作来观察生命周期执行顺序')
}

// 组件初始化完成提示
console.log('✅ [Parent] 父组件setup完成，准备进入挂载阶段')
</script>

<style scoped lang="scss">
// 复杂渐变背景用sass实现
.parent-component {
  @apply p-5 rounded-xl text-white my-5;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

// 警告提示框样式用sass实现
.update-note {
  @apply rounded-md p-3 mb-4;
  background: rgba(255, 193, 7, 0.2);
  border: 1px solid rgba(255, 193, 7, 0.4);
}

// 状态项样式
.status-item {
  @apply p-2 rounded transition-all duration-300;

  &.pending {
    @apply bg-white bg-opacity-10;
    border-left: 4px solid #ffa500;
  }

  &.executed {
    background: rgba(76, 175, 80, 0.2);
    border-left: 4px solid #4caf50;
    animation: pulse 0.5s ease-in-out;
  }
}

// 控制按钮样式
.control-btn {
  @apply px-6 py-3 rounded-full text-white cursor-pointer transition-all duration-300;
  background: rgba(255, 255, 255, 0.2);
  border: 2px solid rgba(255, 255, 255, 0.3);
  backdrop-filter: blur(10px);

  &:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  }

  &:active {
    transform: translateY(0);
  }
}

// 动画效果用sass实现
@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
  100% {
    transform: scale(1);
  }
}
</style>
